import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class PicBean {
  String name;
  int id;
  int index = 0;
  PicBean(this.name, this.id);

  setIndex(int index) {
    this.index = index;
    return this;
  }

  @override
  String toString() {
    return "PicBean(name=$name, id=$id, index=$index)";
  }
}

class PicturePage extends StatefulWidget {
  const PicturePage({super.key});
  @override
  State<PicturePage> createState() => _PicturePageState();
}

class _PicturePageState extends State<PicturePage> {
  List<PicBean> pics = [
    PicBean("assets/images/1.png", 0),
    PicBean("assets/images/2.jpeg", 0),
    PicBean("assets/images/3.jpeg", 0),
    PicBean("assets/images/4.jpg", 0),
    PicBean("assets/images/6.jpg", 0),
    PicBean("assets/images/1.png", 0),
    PicBean("assets/images/2.jpeg", 0),
    PicBean("assets/images/3.jpeg", 0),
    PicBean("assets/images/4.jpg", 0),
    PicBean("assets/images/6.jpg", 0),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("daex_texture"),
      ),
      body: ListView.builder(
        itemCount: pics.length + 1,
        itemBuilder: (context, index) {
          if (index == pics.length) {
            return _buildBottom(context);
          }
          PicBean picBean = pics[index];
          return PictureWidget(bean: picBean);
        },
      ),
    );
  }

  @override
  void initState() {
    debugPrint("_PicturePageState initState");
    super.initState();
  }

  @override
  void dispose() {
    debugPrint("_PicturePageState dispose");
    super.dispose();
  }
}

_buildBottom(BuildContext context) {
  return Center(
    child: ElevatedButton(
      onPressed: () {
        _gotoNextPage(context);
      },
      child: const Text("跳转"),
    ),
  );
}

_gotoNextPage(BuildContext context) {
  Navigator.push(context, MaterialPageRoute(
    builder: (BuildContext context) {
      return const PicturePage();
    },
  ));
}

class PictureWidget extends StatefulWidget {
  const PictureWidget({super.key, required this.bean});
  final PicBean bean;

  @override
  State<PictureWidget> createState() => _PictureWidgetState(bean);
}

class _PictureWidgetState extends State<PictureWidget> {
  final PicBean bean;
  bool isDisposed = false;

  _PictureWidgetState(this.bean);

  @override
  void initState() {
    super.initState();
    registerTexture(bean.name).then((value) {
      bean.id = value;
      if (isDisposed) {
        // 已执行了 dispose 方法
        // dispose 执行后再调用 setState 会报错
        // 此时需要执行 unregisterTexture ，避免内存泄露
        unregisterTexture(value);
      } else {
        setState(() {});
      }
    }).catchError((e) {
      debugPrint("registerTexture error: $e");
    });
  }

  @override
  void dispose() {
    isDisposed = true;
    unregisterTexture(bean.id).then((value) => {}).catchError((e) {
      debugPrint("unregisterTexture error: $e");
    });
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return bean.id > 0
        ? getTextureBody(context, bean)
        : const Text('loading...');
  }

  Widget getTextureBody(BuildContext context, PicBean picBean) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        SizedBox(
          width: 300,
          height: 300,
          child: Texture(textureId: picBean.id),
        ),
        Container(
          height: 10,
        ),
      ],
    );
  }
}

const MethodChannel _channel = MethodChannel('PictureChannel');

Future<int> registerTexture(String picName) async {
  int id = await _channel.invokeMethod("registerTexture", {'pic': picName});
  return id;
}

Future<void> unregisterTexture(int textureId) async {
  await _channel.invokeMethod('unregisterTexture', {'textureId': textureId});
}
